<!--
 * @FilePath: EditModule.vue
 * @Author: jack
 * @Date: 2024-05-14 11:55:45
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2024-07-08 19:06:37
 * Copyright: 2024 xxxTech CO.,LTD. All Rights Reserved.
 * @Descripttion: 
-->
<template>
    <Model :title="editId ? '编辑大屏' : '添加大屏'" :modelShow="props.modelShow" width="680px" @cancel="Cancel(ruleFormRef)"
        @confirm="Confirm(ruleFormRef)">
        <el-form :model="ruleForm" :rules="rules" ref="ruleFormRef" label-width="82px" status-icon>
            <el-row :gutter="10">
                <el-col :span="24">
                    <el-form-item label="大屏名称" prop="screen_name">
                        <el-input clearable placeholder="请输入大屏名称" v-model="ruleForm.screen_name">
                        </el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="大屏链接" prop="screen_link">
                        <el-input v-model="ruleForm.screen_link" placeholder="请输入大屏链接"></el-input>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="上传封面" prop="pic">
                        <div class="uploadList">
                            <div style="display: inline-block;height: 72px">
                                <el-upload class="avatar-uploader" :show-file-list="false"
                                    :on-success="handleAvatarSuccess" :http-request="uploadAvatorAdd"
                                    :before-upload="beforeAvatarUpload">
                                    <el-icon class="avatar-uploader-icon">
                                        <Plus />
                                    </el-icon>
                                    <div>点击上传封面图</div>
                                </el-upload>
                            </div>
                            <div class="items" v-if="ruleForm.pic" @mouseenter="mouserIndex = 1"
                                @mouseleave="mouserIndex = -1">
                                <el-image :src="ruleForm.pic" fit="cover" style="width: 100%;height: 100%;"></el-image>
                                <transition name="fade" mode="out-in">
                                    <div class="model-img-box" v-if="mouserIndex == 1">
                                        <div class="mine-flex-box">
                                            <el-icon @click="showImage">
                                                <View />
                                            </el-icon>
                                            <span></span>
                                            <el-icon @click="handleRemove">
                                                <Delete />
                                            </el-icon>
                                        </div>
                                    </div>
                                </transition>
                            </div>
                        </div>
                    </el-form-item>
                </el-col>
                <el-col :span="24">
                    <el-form-item label="备注" prop="remark">
                        <el-input type="textarea" v-model="ruleForm.remark" placeholder="请输入备注"></el-input>
                    </el-form-item>
                </el-col>
            </el-row>
        </el-form>
    </Model>
    <!-- 查看图片 -->
    <el-image-viewer v-if="showViewer" @close="closeViewer" :url-list="srcList"></el-image-viewer>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, FormRules, UploadInstance } from 'element-plus'
import { UploadProps, UploadRequestOptions } from 'element-plus'
import * as imageConversion from 'image-conversion'; // 图片压缩
import upload from '../../../util/OSSUpload'
import $util from '../../../util/util'
import { getMaterList, materialSetting } from '../../Api/index'
interface PropsType {
    // 是否显示弹窗
    modelShow?: boolean
    dataList?: any
    typeId?: any
    editIndex?: number
}
const props = withDefaults(defineProps<PropsType>(), {
    modelShow: false,
    dataList: [],
    typeId: '',
    editIndex: -1
})
const emit = defineEmits<EmitType>()
interface EmitType {
    (e: 'CancelModule'): void
    (e: 'getList'): void
    (e: 'changeData', item: any): void
}
watch(
    () => [props.editIndex, props.modelShow],
    (newValue, oldValue) => {
        if (props.modelShow) {
            if (props.editIndex !== -1) {
                // 编辑
                ruleForm.value = JSON.parse(JSON.stringify(props.dataList[props.editIndex]))
            } else {
                ruleForm.value.id = $util.generateUniqueId(props.dataList)
            }
        }
    },
    { deep: true }
)
const ruleForm = ref<any>({
    id: '',
    screen_name: '',
    screen_link: '',
    pic: '',
    remark: '',
    local_pic: ''
})
const ruleFormRef = ref<FormInstance>()
const rules = reactive<FormRules>({
    screen_name: [{ required: true, message: '请输入大屏名称', trigger: 'blur' }],
    screen_link: [{ required: true, message: '请输入大屏链接', trigger: 'blur' }],
    pic: [{ required: true, message: '请上传大屏封面图', trigger: 'blur' }],
})
const editId = ref<string>('')
// 查看图片
const mouserIndex = ref(-1)
const srcList = ref<any>([])
const showViewer = ref(false)// 显示查看器
// 查看图片
const showImage = () => {
    srcList.value = []
    srcList.value.push(ruleForm.value.pic)
    showViewer.value = true
}
const closeViewer = () => {
    showViewer.value = false
}
// 上传图片
const beforeAvatarUpload: UploadProps['beforeUpload'] = rawFile => {
    const typeList = ['image/jpeg', 'image/png']
    const isTypeValid = typeList.includes(rawFile.type)
    // const isLt2M = rawFile.size / 1024 / 1024 < 2
    if (!isTypeValid) {
        ElMessage.error('请上传正确的图片!')
        return false
    }
    // if (!isLt2M) {
    //     Message.error('上传图片大小不能超过2M!')
    //     return false
    // }
    const params: any = { size: 200, type: 'image/jpeg' }
    return new Promise(async (resolve, reject) => {
        if (rawFile.size / 1024 > 300) { // 大于 300 kb 就压缩
            let file: any = await pngToWhiteBg(rawFile)
            const fileOfBlob = new File([file], `${new Date().getTime()}.png`, { type: file.type })
            imageConversion.compressAccurately(fileOfBlob, 250).then(res => {
                console.log(res)
                resolve(res)
            })
        } else if (isTypeValid) {
            // 无需压缩直接返回原文件
            resolve(rawFile)
        } else {
            reject()
        }
    })
}
const pngToWhiteBg = async (file: any) => {
    let read = new FileReader();
    read.readAsDataURL(file); // 文件转base64
    return new Promise((resolve, reject) => {
        read.onload = (e: any) => {
            let img: any = new Image();
            img.src = e.target.result;
            img.onload = async () => {
                // 生成canvas
                let canvas = document.createElement("canvas");
                let context: any = canvas.getContext("2d");
                // 绘制图片到canvas上
                canvas.width = img.width;
                canvas.height = img.height;

                // 在canvas绘制前填充白色背景
                context.fillStyle = "#fff";
                context.fillRect(0, 0, canvas.width, canvas.height);
                context.drawImage(img, 0, 0);
                let base64 = canvas.toDataURL(file["type"], 1);
                let newFile = dataUrlToFile(base64);
                resolve(newFile);
            }
        }
    })
}
const dataUrlToFile = async (dataurl: any) => {
    let arr = dataurl.split(","),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], { type: mime });
}
const handleAvatarSuccess: UploadProps['onSuccess'] = (
    response,
    uploadFile
) => {
}
const uploadAvatorAdd = async (options: UploadRequestOptions) => {
    upload(options.file, 'pic', (res: any) => {
        ruleForm.value.local_pic = ""
        ruleForm.value.pic = res.inch
        mouserIndex.value = -1
    },
        (error: any) => {
            console.log(error)
        },
        (percent: any) => {
            console.log(percent)
        }
    )
}
const handleRemove = () => {
    ruleForm.value.local_pic = ''
    ruleForm.value.pic = ''
}
const Cancel = async (formEl: FormInstance | undefined) => {
    if (!formEl) return
    formEl.resetFields()
    reset()
    emit('CancelModule')
}
const reset = () => {
    ruleForm.value = {
        id: '',
        screen_name: '',
        screen_link: '',
        pic: '',
        remark: ''
    }
}
// 点击确定编辑或者新增
const Confirm = async (formEl: FormInstance | undefined) => {
    if (!formEl) return
    formEl.validate(async (valid: any) => {
        if (valid) {
            let arr: any = []
            if (props.editIndex !== -1) {
                // 如果是编辑
                arr = props.dataList
                arr[props.editIndex] = ruleForm.value
            } else {
                // 如果是添加
                arr = props.dataList
                arr.unshift(ruleForm.value)
            }
            const res: any = await materialSetting({ type_id: props.typeId, content: arr })
            if (res.code !== 1) return ElMessage.error(res.message)
            emit('getList')
            ElMessage.success(res.message)
            reset()
            emit('CancelModule')
        } else {
            console.log('error submit!')
        }
    })
}
onMounted(() => {
})
</script>
<style lang="scss" scoped>
.uploadList {
    display: flex;
    flex-flow: wrap;
    width: 100%;

    .items {
        width: 120px;
        height: 72px;
        background: #EEEEEE;
        display: inline-block;
        margin: 0 0 0 20px;
        border-radius: 4px;
        border: 1px dashed #DCDCDC;
        position: relative;
        padding: 6px;
        box-sizing: border-box;

        .el-image {
            border-radius: 4px;
            background: #ffffff
        }

        .model-img-box {
            background: rgba(0, 0, 0, 0.5);
            width: 100%;
            height: 72px;
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            border-radius: 4px;
            z-index: 9;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #fff;

            i {
                color: #fff;
                font-size: 16px;
            }

            .mine-flex-box {
                display: flex;
                width: 65%;
                justify-content: space-between;
                align-items: center;

                .el-icon {
                    transition: all 1s;
                    font-weight: bold;
                }

                span {
                    width: 1px;
                    margin: 0 7px;
                    height: 12px;
                    background: rgba(255, 255, 255, 0.9);
                    display: inline-block;
                }

                .el-icon:first-of-type:hover {
                    transform: scale(1.2);
                }

                .el-icon:last-of-type:hover {
                    transform: scale(1.2);
                }

                :deep(.avatar-uploader) {
                    width: 16px;
                    height: 16px;
                    margin: 0px;


                }

                :deep(.avatar-uploader .el-upload) {
                    width: 16px;
                    height: 16px;
                    border: none;
                    background-color: transparent;
                }
            }

            .zoom-big-box {
                display: flex;
                align-items: center;
                transition: all 1s;
            }
        }
    }
}

:deep(.avatar-uploader .el-upload) {
    width: 120px;
    height: 72px;
    background: #EEEEEE;
    border-radius: 4px;
    border: 1px dashed #DCDCDC;
    font-size: 12px;
    color: rgba(0, 0, 0, 0.4);
    box-sizing: border-box;
}

:deep(.el-icon.avatar-uploader-icon) {
    color: #000000;
    margin-bottom: 3px;
    font-size: 14px;
    font-weight: 600;
}

:deep(.avatar-uploader) {
    margin: 0px;
    width: 120px;
}
</style>
